# -*- coding: utf-8 -*-
"""
基于 ECharts 的折线图组件
"""
from .echarts_base import TgEchartsBase
from pyecharts.charts import Line
from pyecharts import options as opts
from pyecharts.commons.utils import JsCode
import pandas as pd
from datetime import datetime
import numpy as np

class TgLineChartEcharts(TgEchartsBase):
    """基于 ECharts 的折线图组件"""

    def __init__(self, title="折线图", parent=None):
        super().__init__(parent)
        self.chart_title = title
        self.series_data = []  # 存储多个系列的数据

    def set_data(self, df: pd.DataFrame, x_column: str, y_column: str, name: str = "数据", color: str = "#5470c6"):
        """
        设置折线图数据
        :param df: 数据DataFrame
        :param x_column: X轴数据列名或直接传入数据
        :param y_column: Y轴数据列名或直接传入数据
        :param name: 系列名称
        :param color: 线条颜色
        """
        self.df = df
        
        # 处理x轴数据
        if isinstance(x_column, str) and x_column in df.columns:
            x_data = df[x_column].tolist()
        else:
            x_data = x_column if hasattr(x_column, '__iter__') else df.index.tolist()
        
        # 处理y轴数据
        if isinstance(y_column, str) and y_column in df.columns:
            y_data = df[y_column].tolist()
        else:
            y_data = y_column if hasattr(y_column, '__iter__') else []
        
        # 转换时间数据为字符串格式：如果为零点则仅显示日期
        x_data_str = []
        for x in x_data:
            if isinstance(x, pd.Timestamp):
                dt = x.to_pydatetime()
                if dt.hour == 0 and dt.minute == 0 and dt.second == 0:
                    x_data_str.append(dt.strftime("%Y-%m-%d"))
                else:
                    x_data_str.append(dt.strftime("%Y-%m-%d %H:%M:%S"))
            elif isinstance(x, datetime):
                dt = x
                if dt.hour == 0 and dt.minute == 0 and dt.second == 0:
                    x_data_str.append(dt.strftime("%Y-%m-%d"))
                else:
                    x_data_str.append(dt.strftime("%Y-%m-%d %H:%M:%S"))
            elif hasattr(x, 'timestamp'):
                dt = datetime.fromtimestamp(x.timestamp())
                if dt.hour == 0 and dt.minute == 0 and dt.second == 0:
                    x_data_str.append(dt.strftime("%Y-%m-%d"))
                else:
                    x_data_str.append(dt.strftime("%Y-%m-%d %H:%M:%S"))
            else:
                x_data_str.append(str(x))
        
        # 清空之前的数据并添加新系列
        self.series_data = []
        self.add_series(x_data_str, y_data, name, color)
        self.update_chart()

    def add_series(self, x_data, y_data, name: str = "数据", color: str = "#5470c6"):
        """添加一个数据系列"""
        # 统一格式化 X 轴：零点仅显示日期，其余显示完整时间
        formatted_x = []
        for x in x_data:
            if isinstance(x, pd.Timestamp):
                dt = x.to_pydatetime()
                if dt.hour == 0 and dt.minute == 0 and dt.second == 0:
                    formatted_x.append(dt.strftime("%Y-%m-%d"))
                else:
                    formatted_x.append(dt.strftime("%Y-%m-%d %H:%M:%S"))
            elif isinstance(x, datetime):
                dt = x
                if dt.hour == 0 and dt.minute == 0 and dt.second == 0:
                    formatted_x.append(dt.strftime("%Y-%m-%d"))
                else:
                    formatted_x.append(dt.strftime("%Y-%m-%d %H:%M:%S"))
            elif hasattr(x, 'timestamp'):
                dt = datetime.fromtimestamp(x.timestamp())
                if dt.hour == 0 and dt.minute == 0 and dt.second == 0:
                    formatted_x.append(dt.strftime("%Y-%m-%d"))
                else:
                    formatted_x.append(dt.strftime("%Y-%m-%d %H:%M:%S"))
            else:
                formatted_x.append(str(x))

        self.series_data.append({
            'x_data': formatted_x,
            'y_data': y_data,
            'name': name,
            'color': color
        })

    def clear(self):
        """清空图表数据"""
        self.series_data = []
        self.df = None
        if hasattr(self, 'webview') and self.webview is not None:
            self.webview.setHtml("<html><head><meta charset='utf-8'><style>html,body{margin:0;padding:0;overflow:hidden;background:transparent;}</style></head><body></body></html>")

    def create_chart(self) -> Line:
        """创建折线图"""
        # 根据当前控件高度设置图表初始化尺寸，宽度自适应
        current_h = self.height() if hasattr(self, 'height') else 0
        height_px = max(160, int(current_h)) if current_h else 220
        init_opts = opts.InitOpts(width="100%", height=f"{height_px}px")
        if not self.series_data:
            chart = Line(init_opts=init_opts)
            chart.set_global_opts(title_opts=opts.TitleOpts(title=self.chart_title))
            return chart

        chart = Line(init_opts=init_opts)

        # 统一 X 轴：收集所有系列的时间点，排序去重后作为唯一的 X 轴
        all_x_values = []
        for series in self.series_data:
            all_x_values.extend(series['x_data'])
        x_axis_data = sorted(set(all_x_values))
        chart.add_xaxis(xaxis_data=x_axis_data)

        # 将每个系列的 Y 值按统一 X 轴对齐（缺失处填 None）
        for series in self.series_data:
            mapping = {x: y for x, y in zip(series['x_data'], series['y_data'])}
            aligned_y = [mapping.get(x, None) for x in x_axis_data]
            chart.add_yaxis(
                series_name=series['name'],
                y_axis=aligned_y,
                itemstyle_opts=opts.ItemStyleOpts(color=series['color']),
                linestyle_opts=opts.LineStyleOpts(color=series['color']),
                label_opts=opts.LabelOpts(is_show=False)
            )
        
        # 设置全局选项
        chart.set_global_opts(
            title_opts=opts.TitleOpts(title=self.chart_title),
            tooltip_opts=opts.TooltipOpts(
                trigger="axis",
                axis_pointer_type="cross"
            ),
            legend_opts=opts.LegendOpts(pos_left="center", pos_top="2%"),
            xaxis_opts=opts.AxisOpts(
                type_="category",
                boundary_gap=False,
                axislabel_opts=opts.LabelOpts(rotate=45),
            ),
            yaxis_opts=opts.AxisOpts(
                type_="value",
                # 控制 Y 轴刻度小数位，避免过长的小数造成左侧占位过大
                axislabel_opts=opts.LabelOpts(
                    formatter=JsCode(
                        """
                        function (value) {
                            var abs = Math.abs(value);
                            if (abs >= 100) {
                                return Number(value).toLocaleString('en-US', {maximumFractionDigits: 0});
                            } else if (abs >= 1) {
                                return Number(value).toLocaleString('en-US', {minimumFractionDigits: 1, maximumFractionDigits: 1});
                            } else {
                                return Number(value).toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2});
                            }
                        }
                        """
                    )
                ),
                is_scale=True,  # 启用自动缩放（pyecharts 2.x 参数名为 is_scale）
                min_="dataMin",  # Y轴最小值自动调整为数据最小值
                max_="dataMax"   # Y轴最大值自动调整为数据最大值
            ),
            # 使用 inside 数据缩放以节省垂直空间
            datazoom_opts=[opts.DataZoomOpts(type_="inside", xaxis_index=0, range_start=0, range_end=100)],
            toolbox_opts=opts.ToolboxOpts(
                feature={
                    "saveAsImage": {},
                    "restore": {},
                    "dataView": {"readOnly": False},
                    "dataZoom": {},
                    "magicType": {"type": ["line", "bar"]}
                }
            ),
        )

        # 收紧网格边距，减少右侧留白（在 pyecharts 2.x 中不在 set_global_opts 里传入）
        chart.options.update(
            grid=opts.GridOpts(
                pos_left="6%",
                pos_right="2%",
                pos_top="15%",
                pos_bottom="12%",
                is_contain_label=True,
            ).opts
        )
        
        return chart

    def update_chart(self):
        """更新图表"""
        chart = self.create_chart()
        self.render_chart(chart)

    def set_time_range(self, start_time, end_time, enforce_limits=True):
        """设置时间范围（为了兼容性保留此方法）"""
        # ECharts 通过 DataZoom 控制范围，这里可以实现具体的时间范围控制
        pass
